﻿using System;
using System.Windows.Threading;

namespace Colorful.Control.Controls
{
    public class FXThreadDispatcher
    {        
        private static FXThreadDispatcher dispatcher;
        private readonly Dispatcher uiThreadDispatcher;
        
        /// <summary>
        /// Ctor
        /// </summary>
        public FXThreadDispatcher()
        {
            uiThreadDispatcher = Dispatcher.CurrentDispatcher;
        }

        public static FXThreadDispatcher Instance
        {
            get
            {
                if (dispatcher == null)
                    InitializeInstance();

                return dispatcher;
            }
            set
            {
                dispatcher = value;
            }
        }

        public static void InitializeInstance()
        {
            Instance = new FXThreadDispatcher();
        }

        public virtual void BeginInvoke(DispatcherPriority priority, Delegate method)
        {
            if (!uiThreadDispatcher.HasShutdownStarted)
            {
                uiThreadDispatcher.BeginInvoke(priority, method);
            }
        }

        public virtual void BeginInvoke(DispatcherPriority priority, Delegate method, object arg)
        {
            if (!uiThreadDispatcher.HasShutdownStarted)
            {
                uiThreadDispatcher.BeginInvoke(priority, method, arg);
            }
        }

        public virtual void BeginInvoke(DispatcherPriority priority, Delegate method, object arg, params object[] args)
        {
            if (!uiThreadDispatcher.HasShutdownStarted)
            {
                uiThreadDispatcher.BeginInvoke(priority, method, arg, args);
            }
        }

        public virtual void Invoke(DispatcherPriority priority, Delegate method)
        {
            if (!uiThreadDispatcher.HasShutdownStarted)
            {
                uiThreadDispatcher.Invoke(priority, method);
            }
        }

        public virtual void Invoke(DispatcherPriority priority, Delegate method, object arg)
        {
            if (!uiThreadDispatcher.HasShutdownStarted)
            {
                if (arg == null)
                {
                    uiThreadDispatcher.Invoke(priority, method);
                }
                else
                {
                    uiThreadDispatcher.Invoke(priority, method, arg);
                }
            }
        }

        public virtual void Invoke(DispatcherPriority priority, Delegate method, object arg, params object[] args)
        {
            if (!uiThreadDispatcher.HasShutdownStarted)
            {
                uiThreadDispatcher.Invoke(priority, method, arg, args);
            }
        }
    }
}
